package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;
    @Autowired
    private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private VodService vodService;
    @Autowired
    private TrackStatMapper trackStatMapper;
	@Qualifier("com.atguigu.tingshu.user.client.UserInfoFeignClient")
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
		try {
			TrackInfo trackInfo = new TrackInfo();
			BeanUtils.copyProperties(trackInfoVo,trackInfo);
			trackInfo.setUserId(userId);
			AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
			trackInfo.setOrderNum(albumInfo.getIncludeTrackCount()+1);
			TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
			//处理流媒体的数据
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaType(mediaInfo.getType());
			trackInfo.setMediaSize(mediaInfo.getSize());
			trackInfoMapper.insert(trackInfo);
			//track_stat
			saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
			saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
			saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
			saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);
			//album_info
			albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
			albumInfoMapper.updateById(albumInfo);
		} catch (BeansException e) {
			log.error("保存声音信息失败：{}",e);
			throw new RuntimeException();
		}

	}
	public void saveTrackStat(Long trackId,String trackType){
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(trackType);
		trackStat.setStatNum(new Random().nextInt(10000));
		trackStatMapper.insert(trackStat);
	}

	@Override
	public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> infoPage, TrackInfoQuery trackInfoQuery) {
		return trackInfoMapper.selectUserTrackPage(infoPage,trackInfoQuery);
	}

	@Override
	public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
		TrackInfo trackInfo = this.getById(trackId);
		String orginMediaFileId = trackInfo.getMediaFileId();
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		if (!orginMediaFileId.equals(trackInfoVo.getMediaFileId())){
			TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
			if (null==mediaInfo){
				throw new GuiguException(ResultCodeEnum.VOD_FILE_ID_ERROR);
			}
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaType(mediaInfo.getType());
			trackInfo.setMediaSize(mediaInfo.getSize());
			//原有视频不要
			vodService.deleteMediaFile(trackInfoVo.getMediaFileId());
		}
		trackInfoMapper.updateById(trackInfo);
	}


	@Override
	public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
		if (SystemConstant.TRACK_STAT_PLAY.equals(trackStatMqVo.getStatType())){
			albumInfoMapper.updateStat(trackStatMqVo.getAlbumId(),trackStatMqVo.getCount(),SystemConstant.TRACK_STAT_PLAY);
			trackInfoMapper.updateStat(trackStatMqVo.getTrackId(),trackStatMqVo.getCount(),SystemConstant.TRACK_STAT_PLAY);
		}else if (SystemConstant.TRACK_STAT_COLLECT.equals(trackStatMqVo.getStatType())){
		}
	}

	@Override
	public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> infoPage, Long albumId, Long userId) {
		//根据专辑id查询声音列表
		IPage<AlbumTrackListVo> iPage = trackInfoMapper.selectAlbumTrackPage(infoPage,albumId);
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//判断用户是否存在
		if (null==userId){
			//判断专辑类型是否付费
			if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())){
				//免费试听集数
				int freeCount =albumInfo.getTracksForFree();
				iPage.getRecords()
						.stream().filter(track -> track.getOrderNum()>freeCount)
						.forEach(track -> track.setIsShowPaidMark(true));
			}
		}else {
			//获取用户信息
			Result<UserInfoVo> result = userInfoFeignClient.getUserInfoVo(userId);
			Assert.notNull(result, "查询用户信息失败");
			UserInfoVo userInfoVo = result.getData();
			Assert.notNull(userInfoVo, "查询用户信息失败");
			//判断专辑是否付费
			boolean ispaid = false;
			if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())){
				if (userInfoVo.getIsVip()==0 ||
						userInfoVo.getIsVip()==1 && userInfoVo.getVipExpireTime().before(new Date())){
					ispaid=true;
				}
			}else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())){
				ispaid=true;
			}
			if (ispaid){
				//根据专辑id和付费声音列表查询用户是否已买过此声音
				//声音id列表
				List<AlbumTrackListVo> albumTrackListVos = iPage.getRecords()
						.stream().filter(track -> track.getOrderNum() > albumInfo.getTracksForFree())
						.collect(Collectors.toList());
				List<Long> trackIdList = albumTrackListVos.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
				Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumId, trackIdList);
				Assert.notNull(mapResult, "查询用户是否已买声音失败");
				Map<Long, Integer> data = mapResult.getData();
				Assert.notNull(data, "查询用户是否已买声音失败");
				//1买过，0未买过
				for (AlbumTrackListVo albumTrackListVo : albumTrackListVos) {
					albumTrackListVo.setIsShowPaidMark(data.get(albumTrackListVo.getTrackId())==0);
				}
			}
		}
		return iPage;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfo(Long trackId) {
		TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
		trackInfoMapper.deleteById(trackId);
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,trackId));
		//修改专辑包含声音总数
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()-1);
		albumInfoMapper.updateById(albumInfo);
		//声音在专辑中排序值
		trackInfoMapper.updateOrderNum(trackInfo.getAlbumId(),trackInfo.getOrderNum());
		vodService.deleteMediaFile(trackInfo.getMediaFileId());
	}
}
